package com.feifan.web.controller.utils;

import com.feifan.common.core.domain.AjaxResult;
import com.feifan.common.utils.DateUtils;
import com.feifan.framework.util.ShiroUtils;
import com.feifan.oa.domain.FlowCategoryInfo;
import com.feifan.oa.domain.Holiday;
import com.feifan.oa.domain.HolidayDate;
import com.feifan.oa.domain.HolidayWorkingDate;
import com.feifan.oa.service.IFlowCategoryInfoService;
import com.feifan.oa.service.IHolidayDateService;
import com.feifan.oa.service.IHolidayWorkingDateService;
import com.feifan.system.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

/**
 * @program: feifan
 * @description 请假工具类
 * @author: Alex
 * @create: 2020-07-11 03:33
 **/
@Component
public class LeaveUtil {

    private static LeaveUtil leaveUtil;
    @Autowired
    private IHolidayDateService holidayDateService;
    @Autowired
    private IHolidayWorkingDateService holidayWorkingDateService;
    @Autowired
    private IFlowCategoryInfoService flowCategoryInfoService;

    /**
     * 获取请假天数1
     * @param startTime 请假开始时间
     * @param endTime   请假结束时间
     * @return 请假天数
     * @throws ParseException
     */
    public static String caulateTotalTime1(Long id, String startTime, String endTime) throws ParseException {
        if (StringUtils.isEmpty(id) || StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
            return "0`:0`:0";
        }

        //记录用户选择的时间中有多少周六日和调休日
        int saturdayAndSunday = 0;
        int restDya = 0;

        //请假的天数转Date
        Date date = DateUtils.parseDate(startTime);
        long d1 = date.getTime();
        Date date1 = DateUtils.parseDate(endTime);
        long d2 = date1.getTime();

        //查看区间天数
        Long l = ((d2 - d1) / (1000 * 60 * 60 * 24)) + 1;

        //假期id
        Holiday holidayEntity = new Holiday();

        //判断是否包含假期
        FlowCategoryInfo flowCategoryInfo =
                leaveUtil.flowCategoryInfoService.selectFlowCategoryInfoById(id);
        if (flowCategoryInfo.getIsHoliday() == 'N') {
            //查询法定节假日
            List<HolidayDate> holidayDates = leaveUtil.holidayDateService.selectHolidayDateList(null);
            for (HolidayDate holiday : holidayDates) {
                //法定节假日开始时间和结束时间
                long start = holiday.getBeginDate().getTime();
                long end = holiday.getFinishDate().getTime();

                //判断请假时间是否在国家法定节假日内
                if (((d1 - start) >= 0) && ((end - d2) >= 0)) {
                    l = l - ((d2 - d1) / (1000 * 60 * 60 * 24)) - 1;
                    holidayEntity = holiday.getHoliday();
                    break;
                } else if (((start - d1) <= 0) && ((end - d2) <= 0) && ((start - d2) <= 0) && ((end - d1) >= 0)) {
                    //请假时间的开始时间在假期时间内   总请假时间出去假期内的天数
                    if (d1 == end) {
                        l = l - ((end - d1) / (1000 * 60 * 60 * 24)) - 1;
                    } else {
                        l = l - ((end - d1) / (1000 * 60 * 60 * 24));
                    }
                    holidayEntity = holiday.getHoliday();
                    break;
                } else if (((start - d1) >= 0) && ((end - d2) >= 0) && ((start - d2) <= 0) && ((end - d1) >= 0)) {
                    //请假时间的结束时间在假期时间内   总请假时间出去假期内的天数
                    if (d2 == start) {
                        l = l - ((d2 - start) / (1000 * 60 * 60 * 24)) - 1;
                    } else {
                        l = l - ((d2 - start) / (1000 * 60 * 60 * 24));
                    }

                    holidayEntity = holiday.getHoliday();
                    break;
                }
            }

            List<String> leaveDays = AccountDateUtil.getEveryday(startTime, endTime);
            //如果请假时间内为周六日则去掉
            for (String leaveDay : leaveDays) {
                if (AccountDateUtil.isWeekend(leaveDay)) {
                    l = l - 1;
                    saturdayAndSunday++;
                }
            }

            //查询当前假期是否有调休时间
            HolidayWorkingDate holidayWorkingDate = new HolidayWorkingDate();
            holidayWorkingDate.setHoliday(holidayEntity);
            List<HolidayWorkingDate> holidayWorkingDates =
                    leaveUtil.holidayWorkingDateService.selectHolidayWorkingDateListByHId(holidayWorkingDate);

            if (!StringUtils.isEmpty(holidayWorkingDates)) {
                //没有调休日期则遍历请假日期的每一天
                for (HolidayWorkingDate workingDate : holidayWorkingDates) {
                    long workingStamp = workingDate.getDate().getTime();
                    for (String result : leaveDays) {
                        long timeStamp = DateUtils.parseDate(result).getTime();
                        //判断请假的日期是否是调休日
                        if (workingStamp == timeStamp) {
                            //总请假天数加1
                            l = l + 1;
                            restDya++;
                        }
                    }
                }
            }
        }

        return saturdayAndSunday + "`:" + restDya + "`:" + (l.intValue() < 0 ? 0 : l.intValue());
    }

    /**
     * 获取请假天数2
     * @param startTime 请假开始时间
     * @param endTime   请假结束时间
     * @return 请假天数
     * @throws ParseException
     */
    public static AjaxResult caulateTotalTime2(Long id, String startTime, String endTime) throws ParseException {
        return AjaxResult.success(caulateTotalTime1(id, startTime, endTime));
    }

    /**
     * 获取请假天数3
     * @param startTime 请假开始时间
     * @param endTime   请假结束时间
     * @return 请假天数
     * @throws ParseException
     */
    public static Integer caulateTotalTime3(Long id, String startTime, String endTime) throws ParseException {
        String[] result = caulateTotalTime1(id, startTime, endTime).split("`:");
        return Integer.parseInt(result[2]);
    }


    /**
     * 验证请假的假期类型
     * @param flowInfoId 流程详情id
     * @return 是否通过
     */
    public static String verificationVacation(Long flowInfoId, Integer days) {
        FlowCategoryInfo flowCategoryInfo = leaveUtil.flowCategoryInfoService.selectFlowCategoryInfoById(flowInfoId);
        String flowCategoryInfoName = flowCategoryInfo.getName();


        //产假
        if ("产假".equals(flowCategoryInfoName)) {
            if (days < 98 || days == 0) {
                return "产假期限最短98天`:98";
            }
        }

        //陪产假
        if ("陪产假".equals(flowCategoryInfoName)) {
            if (days < 7 || days > 31 || days == 0) {
                return "陪产假期限最短为7天最长有1个月`:7";
            }
        }

        //探亲假
        if ("探亲假".equals(flowCategoryInfoName)) {
            SysUser sysUser = ShiroUtils.getSysUser();
            Date date = new Date();
            int day = (int) ((date.getTime() - sysUser.getCreateTime().getTime()) / (1000 * 3600 * 24));
            if (day < 365 || days == 0) {
                return "探亲假条件工作满一年,您当前的工作时间为" + day + "天";
            }
        }

        //婚假
        if ("婚假".equals(flowCategoryInfoName)) {
            if (days < 3 || days == 0) {
                return "婚假期限最短为3天`:3";
            }
        }

        return days.toString();
    }

    @PostConstruct
    public void init() {
        leaveUtil = this;
        leaveUtil.holidayDateService = this.holidayDateService;
        leaveUtil.holidayWorkingDateService = this.holidayWorkingDateService;
        leaveUtil.flowCategoryInfoService = this.flowCategoryInfoService;
    }

}


